/*
 * useStorage - IndexedDB 存储组合式函数（最小实现 + 持久化）
 * 提供对话与消息的本地存储封装，保持同步API并在后台进行IndexedDB持久化
 */

/**
 * 生成随机ID
 * @returns {string} ID
 */
function rid() {
  return Math.random().toString(36).slice(2) + Date.now().toString(36);
}

// ---- IndexedDB 初始化与工具函数（最小实现） ----
let dbPromise = null;

/**
 * 初始化IndexedDB
 * @returns {Promise<IDBDatabase|null>} 数据库实例或null（失败回退）
 */
function initDB() {
  if (typeof indexedDB === 'undefined') return Promise.resolve(null);
  if (dbPromise) return dbPromise;

  dbPromise = new Promise((resolve) => {
    try {
      const req = indexedDB.open('travel-assistant', 1);
      req.onupgradeneeded = (e) => {
        const db = req.result;
        if (!db.objectStoreNames.contains('conversations')) {
          db.createObjectStore('conversations', { keyPath: 'id' });
        }
        if (!db.objectStoreNames.contains('messages')) {
          const store = db.createObjectStore('messages', { keyPath: 'id' });
          store.createIndex('conversationId', 'conversationId', { unique: false });
          store.createIndex('timestamp', 'timestamp', { unique: false });
        }
      };
      req.onsuccess = () => resolve(req.result);
      req.onerror = () => resolve(null);
    } catch (_) {
      resolve(null);
    }
  });
  return dbPromise;
}

/**
 * 后台写入对象到指定store
 * @param {string} storeName - 对象仓库名称
 * @param {Object} value - 写入的对象
 */
async function idbPut(storeName, value) {
  const db = await initDB();
  if (!db) return;
  try {
    const tx = db.transaction(storeName, 'readwrite');
    const store = tx.objectStore(storeName);
    store.put(value);
  } catch (_) { /* noop */ }
}

/**
 * 根据索引查询消息（最小实现）
 * @param {string} conversationId - 对话ID
 * @returns {Promise<Array>} 消息数组
 */
async function idbListMessages(conversationId) {
  const db = await initDB();
  if (!db) return [];
  try {
    return await new Promise((resolve) => {
      const tx = db.transaction('messages', 'readonly');
      const store = tx.objectStore('messages');
      const idx = store.index('conversationId');
      const req = idx.getAll(conversationId);
      req.onsuccess = () => resolve(req.result || []);
      req.onerror = () => resolve([]);
    });
  } catch (_) {
    return [];
  }
}

// ---- 内存结构（同步返回，前端体验更好） ----
const conversations = new Map();
const messages = new Map();

// 初始化状态标记
let isInitialized = false;
let initPromise = null;

/**
 * useStorage 提供内存回退 + IndexedDB后台持久化
 * @returns {{ createConversation: Function, addMessage: Function, listMessages: Function, setTitle: Function }}
 */
export function useStorage() {
  /**
   * 创建对话
   * @param {string} [title] 标题
   * @returns {{id:string, title:string, timestamp:number}}
   */
  function createConversation(title = '新对话') {
    const id = rid();
    const conv = { id, title, timestamp: Date.now(), messageCount: 0, lastMessage: '' };
    conversations.set(id, conv);
    messages.set(id, []);
    // 后台持久化
    idbPut('conversations', conv);
    return conv;
  }

  /**
   * 设置对话标题
   * @param {string} id 对话ID
   * @param {string} title 标题
   */
  function setTitle(id, title) {
    const conv = conversations.get(id);
    if (conv) {
      conv.title = title;
      idbPut('conversations', conv);
    }
  }

  /**
   * 新增消息
   * @param {string} conversationId 对话ID
   * @param {object} msg 消息对象（至少包含sender, content, type, status）
   * @returns {object} 插入后的消息对象（带id与timestamp）
   */
  function addMessage(conversationId, msg) {
    const list = messages.get(conversationId) || [];
    const payload = { ...msg, id: rid(), timestamp: Date.now(), conversationId };
    list.push(payload);
    messages.set(conversationId, list);

    const conv = conversations.get(conversationId);
    if (conv) {
      conv.messageCount = list.length;
      conv.lastMessage = msg.content || '';
      idbPut('conversations', conv);
    }
    // 后台持久化消息
    idbPut('messages', payload);
    return payload;
  }

  /**
   * 列出消息（优先返回内存，若无则尝试IndexedDB）
   * @param {string} conversationId 对话ID
   * @returns {Array} 消息数组
   */
  function listMessages(conversationId) {
    const list = messages.get(conversationId);
    if (list && list.length) return list;

    // 内存为空时，返回空数组（由switchConversation调用restoreMessages来处理异步加载）
    return [];
  }

  // 新增：列出所有会话（IndexedDB）
  /**
   * 从IndexedDB列出所有会话
   * @returns {Promise<Array>} 会话数组
   */
  async function idbListConversations() {
    const db = await initDB();
    if (!db) return [];
    try {
      return await new Promise((resolve) => {
        const tx = db.transaction('conversations', 'readonly');
        const store = tx.objectStore('conversations');
        const req = store.getAll();
        req.onsuccess = () => resolve(req.result || []);
        req.onerror = () => resolve([]);
      });
    } catch (_) {
      return [];
    }
  }

  // 新增：按主键删除
  /**
   * 删除指定store中的主键记录
   * @param {('conversations'|'messages')} storeName - 表名
   * @param {string} key - 主键
   * @returns {Promise<boolean>} 是否删除成功
   */
  async function idbDeleteByKey(storeName, key) {
    const db = await initDB();
    if (!db) return false;
    try {
      return await new Promise((resolve) => {
        const tx = db.transaction(storeName, 'readwrite');
        const store = tx.objectStore(storeName);
        const req = store.delete(key);
        req.onsuccess = () => resolve(true);
        req.onerror = () => resolve(false);
      });
    } catch (_) {
      return false;
    }
  }

  // 新增：按conversationId删除所有消息
  /**
   * 删除指定对话的所有消息（IndexedDB）
   * @param {string} conversationId - 对话ID
   * @returns {Promise<number>} 删除的条数
   */
  async function idbDeleteMessagesByConversation(conversationId) {
    const db = await initDB();
    if (!db) return 0;
    try {
      return await new Promise((resolve) => {
        let count = 0;
        const tx = db.transaction('messages', 'readwrite');
        const store = tx.objectStore('messages');
        const idx = store.index('conversationId');
        const range = IDBKeyRange.only(conversationId);
        const cursorReq = idx.openCursor(range);
        cursorReq.onsuccess = (e) => {
          const cursor = e.target.result;
          if (cursor) {
            store.delete(cursor.primaryKey);
            count += 1;
            cursor.continue();
          } else {
            resolve(count);
          }
        };
        cursorReq.onerror = () => resolve(count);
      });
    } catch (_) {
      return 0;
    }
  }

  /**
   * 初始化存储（从IndexedDB恢复数据到内存）
   * @returns {Promise<void>} 初始化完成
   */
  async function initializeStorage() {
    if (isInitialized) return initPromise;
    if (initPromise) return initPromise;

    initPromise = (async () => {
      try {
        // 恢复会话列表
        const convs = await idbListConversations();
        if (convs && convs.length) {
          convs.forEach((conv) => conversations.set(conv.id, conv));
        }
        isInitialized = true;
      } catch (error) {
        console.warn('初始化存储失败:', error);
        isInitialized = true; // 即使失败也标记为已初始化，避免重复尝试
      }
    })();

    return initPromise;
  }

  /**
   * 列出会话（优先内存，确保初始化后返回）
   * @returns {Array} 会话数组（按时间倒序）
   */
  function listConversations() {
    const arr = Array.from(conversations.values());
    if (arr.length > 0 || isInitialized) {
      return arr.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
    }

    // 如果还未初始化，触发初始化（异步）
    if (!initPromise) {
      initializeStorage();
    }

    return [];
  }

  /**
   * 删除会话（含消息）
   * @param {string} id - 会话ID
   * @returns {Promise<boolean>} 是否成功
   */
  async function deleteConversation(id) {
    conversations.delete(id);
    messages.delete(id);
    const okConv = await idbDeleteByKey('conversations', id);
    await idbDeleteMessagesByConversation(id);
    return !!okConv;
  }

  /**
   * 主动恢复指定会话的消息到内存（从IndexedDB）
   * @param {string} conversationId - 会话ID
   * @returns {Promise<Array>} 恢复后的消息列表
   */
  async function restoreMessages(conversationId) {
    // 先检查内存中是否已有数据
    const existingList = messages.get(conversationId);
    if (existingList && existingList.length > 0) {
      return existingList;
    }

    // 从IndexedDB恢复数据
    const rows = await idbListMessages(conversationId);
    if (rows && rows.length) {
      // 按时间排序确保消息顺序正确
      const sortedRows = rows.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0));
      messages.set(conversationId, sortedRows);

      // 更新会话的消息统计
      const conv = conversations.get(conversationId);
      if (conv) {
        conv.messageCount = sortedRows.length;
        conv.lastMessage = sortedRows[sortedRows.length - 1]?.content || '';
        idbPut('conversations', conv);
      }

      return sortedRows;
    }

    // 没有消息时返回空数组
    return [];
  }

  /**
   * 更新消息状态
   * @param {string} messageId - 消息ID
   * @param {string} status - 新状态
   * @returns {boolean} 是否更新成功
   */
  function updateMessageStatus(messageId, status) {
    // 遍历所有会话的消息，找到对应消息并更新状态
    for (const [conversationId, messageList] of messages.entries()) {
      const message = messageList.find(msg => msg.id === messageId);
      if (message) {
        message.status = status;
        // 后台持久化更新
        idbPut('messages', message);
        return true;
      }
    }
    return false;
  }

  return {
    createConversation,
    setTitle,
    addMessage,
    listMessages,
    listConversations,
    deleteConversation,
    restoreMessages,
    updateMessageStatus,
    initializeStorage
  };
}